# -*- coding: utf-8 -*-
"""
Module Description:
Date: 2017/3/7
Author:FQ
"""
from operator import mul
from pyshare.const.enums.activity import ActivityType
import zope.component
from pyshare.dal.gameconfig.game_env import get_config_env_set
from pyshare.bll.errors import HaremError
import pyshare.bll.events as events
from pyshare.framework.error_handle import GameException
from pyshare.utils.json_utils import dumps, loads
from pyshare.const.lang.tips_info import TipsInfo


class ConcubineMixin(object):
    __slots__ = ()
    _record = NotImplemented
    title = NotImplemented
    intimate_lev = NotImplemented
    skill_lev = NotImplemented
    attribute = NotImplemented
    role_id = NotImplemented
    cfg_id = NotImplemented

    def modify_attribute_and_update_activity(self, val):
        """修改属性，并触发限时活动事件"""
        add_value = sum(val) - sum(self.attribute)
        self._record.Attribute = dumps(val)
        if add_value > 0:
            event = events.ActivityProgressChanged(role_id=self._record.RoleGuid,
                                                   a_type=ActivityType.ConcubineAttribute,
                                                   add_value=add_value)
            zope.component.handle(event)

    def modify_force_and_update_activity(self, val):
        """修改势力点，并触发限时活动事件"""
        add_value = val - self._record.ForceValue
        self._record.ForceValue = val
        if add_value > 0:
            event = events.ActivityProgressChanged(role_id=self._record.RoleGuid,
                                                   a_type=ActivityType.ConcubineForce,
                                                   add_value=add_value)
            zope.component.handle(event)

    def modify_title_exp_and_update_activity(self, val):
        """修改妃位经验，并触发限时活动事件"""
        add_value = val - self._record.TitleExp
        self._record.TitleExp = val
        if add_value > 0:
            event = events.ActivityProgressChanged(role_id=self._record.RoleGuid,
                                                   a_type=ActivityType.TitleExp,
                                                   add_value=add_value)
            zope.component.handle(event)

    @property
    def addition_intimate_lev(self):
        # 获取加上妃位加成的亲密等级
        # cfg = getProfile('TcConcubineTitle', Id=self.title)
        # if not cfg:
        #     return self.intimate_lev
        # return self.intimate_lev + cfg.AwardIntimateLv
        # 新规则不加成亲密等级
        return self.intimate_lev

    def update_intimate_lev(self, val):
        """V2.7增加可降级支持"""
        from pyshare.dal.gameconfig.query import getProfile, getProfileList
        # 自动更新亲密等级
        left = val
        lv = self.intimate_lev
        base = get_config_env_set('UpgrateIntimateLvExp')
        while True:
            if left >= 0:
                # 亲密增加
                lev_cfg = getProfile('TcConcubineIntimateLev', Lv=lv + 1)
                if lev_cfg:
                    if lev_cfg.NeedValue <= left:
                        left -= lev_cfg.NeedValue
                        lv += 1
                    else:
                        break
                else:
                    lv += left // base
                    left %= base
                    break
            else:
                # 亲密扣除
                if lv <= 1:
                    raise GameException(TipsInfo.ConcubineKeys.intimateLvNotEnough)
                lev_cfg = getProfile('TcConcubineIntimateLev', Lv=lv)
                if lev_cfg:
                    left += lev_cfg.NeedValue
                    lv -= 1
                else:
                    left += base
                    lv -= 1
                if left >= 0:
                    break

        self._record.Intimate = left
        if lv > self.intimate_lev:
            self.intimate_lev = lv
            # 妃子技能解锁
            from app.area.core.component_center import ComponentCenter
            ComponentCenter().concubine.unlock_power_skill(self)
        elif lv < self.intimate_lev:
            # 妃子技能回退
            for index, lock_lv in enumerate(self.power_config['UnlockSkill']):
                if lv < lock_lv <= self.intimate_lev:
                    self.lock_skill(index)
            self.intimate_lev = lv

    @property
    def power_lev(self):
        from pyshare.dal.gameconfig.query import getProfile
        # 获取势力等级
        title_cfg = getProfile('TcConcubineTitle', Id=self.title)
        title = title_cfg.getJson()
        return title['PowerLv']

    @property
    def config(self):
        from pyshare.dal.gameconfig.query import getProfile
        # 妃子配置
        cfg = getProfile('TcConcubine', Id=self.cfg_id)
        if not cfg:
            raise HaremError(TipsInfo.ConcubineKeys.skillLevCfgError)
        return cfg.getJson()

    @property
    def power_config(self):
        from pyshare.dal.gameconfig.query import getProfile
        # 势力配置
        cfg = getProfile('TcPower', PowerClass=self.config['PowerClass'])
        if not cfg:
            raise HaremError(TipsInfo.ConcubineKeys.powerCfgError)
        return cfg.getJson()

    @property
    def skill_unlock(self):
        # 是否有没解锁技能
        return not reduce(mul, self.skill_lev)

    def unlock_skill(self, index):
        # 解锁技能
        tem = self.skill_lev
        tem[index] = 1
        self.skill_lev = tem

    def lock_skill(self, index):
        # 回退技能
        tem = self.skill_lev
        tem[index] = 0
        self.skill_lev = tem

    def update_skill(self, index):
        # 升级技能
        tem = self.skill_lev
        tem[index] += 1
        self.skill_lev = tem

    def skill_type(self, index):
        # 获取技能类型
        return self.power_config['SkillList'][index]['SType']

    def skill_max(self, index):
        from pyshare.dal.gameconfig.query import getProfileList
        # 技能是否达到最大等级
        skill_type = self.skill_type(index)
        p_list = getProfileList('TcPowerSkillLev', order_by='Lv', SkillType=skill_type)
        max_lev = p_list[-1].Lv if p_list else 0
        return self.skill_lev[index] >= max_lev

    @property
    def title_max(self):
        from pyshare.dal.gameconfig.query import getProfile, getProfileList
        # 妃位是否达到最大等级
        t_list = getProfileList('TcConcubineTitle', order_by='Id')
        max_lev = t_list[-1].Id if t_list else 1
        return self.title >= max_lev

    @property
    def children(self):
        from pyshare.dal.repository_impl import PrinceRepository
        return PrinceRepository.count_prince_by_rid_mother_id(self.role_id, self.cfg_id)

    @property
    def luck_cost(self):
        return min(self.addition_intimate_lev * 10, 1000)

    def power_buff_addition(self, buff_data):
        # 获取妃子势力Buff加成值字典
        # return：{BType:[v, p]}

        if not buff_data:
            buff_data = dict()
        power_lev = self.power_lev
        power_cfg = self.power_config

        for index, buff_type in enumerate(power_cfg['PowerBuffList']):

            if buff_type not in buff_data:
                buff_data[buff_type] = [0, 0]
            buff_data[buff_type][0] += power_cfg['PowerBuffInitial'][index][0] + power_cfg['PowerBuffUpdate'][index][0] * (power_lev - 1)
            buff_data[buff_type][1] += power_cfg['PowerBuffInitial'][index][1] + power_cfg['PowerBuffUpdate'][index][1] * (power_lev - 1)

        return buff_data

    def power_skill_buff_addition(self, buff_data):
        from pyshare.dal.gameconfig.query import getProfile, getProfileList
        # 获取妃子势力技能Buff加成值字典
        # return：{BType:[v, p]}
        if not buff_data:
            buff_data = dict()
        skill_lev = self.skill_lev
        power_config = self.power_config
        buff_list = power_config['SkillBuffList']

        for index, lev in enumerate(skill_lev):
            if not lev:
                continue
            lev_cfg = getProfile('TcPowerSkillLev', SkillType=power_config['SkillList'][index]['SType'], Lv=lev)
            add_list = lev_cfg.Addition

            for b_index in power_config['SkillList'][index]['BuffIndex']:
                buff_type = buff_list[b_index]
                if buff_type not in buff_data:
                    buff_data[buff_type] = [0, 0]
                buff_data[buff_type][0] += add_list[0]
                buff_data[buff_type][1] += add_list[1]
        return buff_data

    def title_buff_addition(self, buff_data):
        # 妃位buff加成字典
        from pyshare.const.enums.role_buff import MinisterIndicators
        from pyshare.dal.gameconfig.query import getProfile
        title_cfg = getProfile('TcConcubineTitle', Id=self.title)
        addition = title_cfg.MinisterFullBuff
        for buff_type in MinisterIndicators:
            if buff_type not in buff_data:
                buff_data[buff_type] = [0, 0]
            if sum(addition) <= 0:
                return buff_data
            buff_data[buff_type][0] += addition[0]
            buff_data[buff_type][1] += float(addition[1])
        return buff_data

    def strength_buff_addition(self, buff_data, strength=None):
        from pyshare.dal.gameconfig.query import getProfile
        # 清帝妃子buff
        if strength and strength.strengthen_lv > 0:
            strength_cfg = getProfile('TcConcubineActivity', ConcubineId=strength.concubine_id)
            buff_list = strength_cfg.StrengthenBuffList
            for f in buff_list:
                buff_type = f[0]
                
                buff = buff_data.get(buff_type, [0, 0])
                buff[0] += f[1] * strength.strengthen_lv
                buff[1] += f[2] * strength.strengthen_lv
                buff_data[buff_type] = buff
        return buff_data
